within BusinessSimulation.MoleculesOfStructure.Actuators;

model Diffusion "Social diffusion via direct contacts and/or a basic conversion rate"
  import BusinessSimulation.Units.*;
  import BusinessSimulation.Constants.*;
  extends Icons.SubsystemActuator;
  Interfaces.Connectors.FlowPort portA "Port connected to stock of potential adopters" annotation(Placement(visible = true, transformation(origin = {-180, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Interfaces.Connectors.FlowPort portB "Port connected to stock of adopters" annotation(Placement(visible = true, transformation(origin = {180, -0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  DataOutPort dataOut "Expandable connector for output" annotation(Placement(visible = true, transformation(origin = {180, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {50, 104}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  DataInPort dataIn if not (hasConstantOtherAdopters and hasConstantOtherPopulation and hasConstantContactRate and hasConstantFractionalAdoptionRate and hasConstantAdoptionFraction) "Expandable connector for input" annotation(Placement(visible = true, transformation(origin = {-175, 90}, extent = {{-10, -10}, {10, 10}}, rotation = -360), iconTransformation(origin = {-50, 100}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  parameter People otherAdopters = unspecified "Other adopters involved in influencing potential adopters" annotation(Dialog(enable = hasConstantOtherAdopters));
  parameter People otherPopulation = unspecified "Other potential contacts that are neighter adopters or potential adopters" annotation(Dialog(enable = hasConstantOtherPopulation));
  parameter Rate contactRate = unspecified "Social contacts per person per period for adopters" annotation(Dialog(enable = hasConstantContactRate));
  parameter Rate fractionalAdoptionRate = unspecified "Basic conversion rate independent from social contacts" annotation(Dialog(enable = hasConstantFractionalAdoptionRate));
  parameter Fraction adoptionFraction = unspecified "Fraction of social contacts that will result in adoption" annotation(Dialog(enable = hasConstantAdoptionFraction));
  parameter Boolean hasConstantOtherAdopters = false "= true, if other adopters are given by the parameter and not by the continuous input" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));
  parameter Boolean hasConstantOtherPopulation = false "= true, if other population is given by the parameter and not by the continuous input" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));
  parameter Boolean hasConstantContactRate = false "= true, if the rate of social contacts is given by the parameter and not by the continuous input" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));
  parameter Boolean hasConstantFractionalAdoptionRate = false "= true, if the fractional adoption rate is given by the parameter and not by the continuous input" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));
  parameter Boolean hasConstantAdoptionFraction = false "= true, if true the adoption fraction is given by the parameter and not by the continuous input" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));
  parameter Boolean nextStageIsInfluencing = true "= true, if true the next stage (adopters) are influencing potential adopters" annotation(Evaluate = true, Dialog(group = "Structural Parameters"));

  encapsulated expandable connector DataOutPort "Output connector"
    import ICON = BusinessSimulation.Icons.DataOutPort;
    import BusinessSimulation.Units.*;
    extends ICON;
    Real conversionRate "Rate of conversion from social interaction";
    Real adoptionRate "Rate of adoption independent of social interaction";
    Real totalAdoptionRate "Total rate of adoption as a sum of conversion and independent adoption";
  end DataOutPort;

  encapsulated expandable connector DataInPort "Input connector"
    import ICON = BusinessSimulation.Icons.DataInPort;
    import BusinessSimulation.Units.*;
    extends ICON;
    Real otherPopulation "Other potential contacts that are neighter adopters or potential adopters";
    Real otherAdopters "Other adopters involved in influencing potential adopters";
    Real fractionalAdoptionRate "Basic adoption rate independent from social contacts";
    Real adoptionFraction "Fraction of social contacts with potential adopters that will result in adoption";
    Real contactRate "Social contacts per person per period for adopters";
  end DataInPort;
protected
  Converters.Add_2 totalAdopters "Sum of adopters and other adopters" annotation(Placement(visible = true, transformation(origin = {100, 45}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Converters.Add_3 totalPotentialContacts "Total population with regard to potential contacts for adopters" annotation(Placement(visible = true, transformation(origin = {-130, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Converters.Add_2 adjustedTotalAdopters "Depending on whether they influence or not the next stage (adopters) has to be added" annotation(Placement(visible = true, transformation(origin = {51.737, 15}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Converters.Gain adoptersNotInfluencing(c = 0) if not nextStageIsInfluencing annotation(Placement(visible = true, transformation(origin = {160, 27.723}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Converters.PassThrough adoptersInfluencing if nextStageIsInfluencing annotation(Placement(visible = true, transformation(origin = {140, 27.723}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Converters.ConstantConverter doNotAddAdopters(value = 0) if nextStageIsInfluencing "Do not add adopters to popoulation as they are already included" annotation(Placement(visible = true, transformation(origin = {105, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Converters.PassThrough addAdoptersToPopulation if not nextStageIsInfluencing "Adopters are not influencing and thus have to be added to potential contacts" annotation(Placement(visible = true, transformation(origin = {105, 15}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Sensors.FlowPortSensor potentialAdopters "Potential Adopters as given by stock connected to port A" annotation(Placement(visible = true, transformation(origin = {-150, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Sensors.FlowPortSensor adopters "Level of adopters as given by stock connected to port B" annotation(Placement(visible = true, transformation(origin = {140, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Flows.Unidirectional.Transition converting "Conversion of potential adopters to adopters" annotation(Placement(visible = true, transformation(origin = {-0, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Converters.ConstantConverter parOtherPopulation(value = otherPopulation) if hasConstantOtherPopulation "Constant opther population (optional)" annotation(Placement(visible = true, transformation(origin = {-145, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.PassThrough u_otherPopulation if not hasConstantOtherPopulation "Continuous input of other population (neither adopter nor potential adopter)" annotation(Placement(visible = true, transformation(origin = {-160, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.Division potAdoptConcentration "Concentration of potential adopters" annotation(Placement(visible = true, transformation(origin = {-86.592, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Converters.PassThrough u_ContactRate if not hasConstantContactRate "Rate of social contacts for adopters" annotation(Placement(visible = true, transformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.ConstantConverter parContactRate(value = contactRate) if hasConstantContactRate "Social contact rate for adopters (people per people per period)" annotation(Placement(visible = true, transformation(origin = {108.491, 75}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.Product_2 contactsAdopters "Contacts with adopters per period" annotation(Placement(visible = true, transformation(origin = {50, 50}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Converters.Product_2 contactsWithPotAdopt "Contacts of adopters with potential adopters" annotation(Placement(visible = true, transformation(origin = {-10, 30}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.PassThrough u_AdoptionFraction if not hasConstantAdoptionFraction "Conversion propability for interaction of potential adopters with adopters" annotation(Placement(visible = true, transformation(origin = {-0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.Product_2 conversionRate "Rate of conversion" annotation(Placement(visible = true, transformation(origin = {-5, -5}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.PassThrough u_FractAdoptRate if not hasConstantFractionalAdoptionRate "Continuous fractional adoption rate" annotation(Placement(visible = true, transformation(origin = {-50, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Flows.Unidirectional.ProportionalTransition adopting(fractionalRate = fractionalAdoptionRate) "Conversion independent from social contacts" annotation(Placement(visible = true, transformation(origin = {-45, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Converters.ConstantConverter parAdoptionFraction(value = adoptionFraction) if hasConstantAdoptionFraction "Constant adoption fraction (optional)" annotation(Placement(visible = true, transformation(origin = {20, 75}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.Add_2 totalAdoptionRate annotation(Placement(visible = true, transformation(origin = {55, -55}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Converters.ConstantConverter parOtherAdopters(value = otherAdopters) if hasConstantOtherAdopters "Constant opther adopters (optional)" annotation(Placement(visible = true, transformation(origin = {160, 80}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.PassThrough u_otherAdopters if not hasConstantOtherAdopters "Continuous input of other adopters envolved in influencing potential adopters" annotation(Placement(visible = true, transformation(origin = {140, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Converters.ConstantConverter parFractAdoptRate(value = fractionalAdoptionRate) if hasConstantFractionalAdoptionRate "Constant fractinal adoption rate (optional)" annotation(Placement(visible = true, transformation(origin = {-30, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
equation
  assert(not hasConstantOtherAdopters or otherAdopters < inf, "Parameter otherAdopters needs to be specified");
  assert(not hasConstantOtherPopulation or otherPopulation < inf, "Parameter otherPopulation needs to be specified");
  assert(not hasConstantContactRate or contactRate < inf, "Parameter contactRate needs to be specified");
  assert(not hasConstantFractionalAdoptionRate or fractionalAdoptionRate < inf, "Parameter fractionalAdoptionRate needs to be specified");
  assert(not hasConstantAdoptionFraction or adoptionFraction <= 1 and adoptionFraction >= 0, "Parameter adoptionFraction needs to be specified");
  connect(portA, potentialAdopters.flowPort) annotation(Line(visible = true, origin = {-165, 0}, points = {{-15, 0}, {15, -0}}, color = {128, 0, 128}));
  connect(portA, converting.portA) annotation(Line(visible = true, origin = {-107.641, -40}, points = {{-72.359, 40}, {-42.359, 40}, {-42.359, 0}, {97.641, 0}}, color = {128, 0, 128}));
  connect(converting.portB, portB) annotation(Line(visible = true, origin = {109.157, -26.667}, points = {{-99.157, -13.333}, {30.843, -13.333}, {30.843, 26.667}, {70.843, 26.667}}, color = {128, 0, 128}));
  connect(adopters.flowPort, portB) annotation(Line(visible = true, origin = {160, -0}, points = {{-20, 0}, {20, -0}}, color = {128, 0, 128}));
  connect(potentialAdopters.stock, potAdoptConcentration.u1) annotation(Line(visible = true, origin = {-131.498, 40.333}, points = {{-18.453, -29.333}, {-18.453, 14.667}, {36.906, 14.667}}, color = {1, 37, 163}));
  connect(u_ContactRate.y, contactsAdopters.u1) annotation(Line(visible = true, origin = {79.333, 57.546}, points = {{10.667, 5.092}, {10.667, -2.546}, {-21.333, -2.546}}, color = {1, 37, 163}));
  connect(parContactRate.y, contactsAdopters.u1) annotation(Line(visible = true, origin = {91.661, 60}, points = {{16.83, 10}, {16.83, -5}, {-33.661, -5}}, color = {1, 37, 163}));
  connect(potAdoptConcentration.y, contactsWithPotAdopt.u2) annotation(Line(visible = true, origin = {-36.41, 46}, points = {{-42.819, 4}, {21.41, 4}, {21.41, -8}}, color = {1, 37, 163}));
  connect(contactsAdopters.y, contactsWithPotAdopt.u1) annotation(Line(visible = true, origin = {10.879, 46}, points = {{31.758, 4}, {-15.879, 4}, {-15.879, -8}}, color = {1, 37, 163}));
  connect(contactsWithPotAdopt.y, conversionRate.u2) annotation(Line(visible = true, origin = {-10, 12.5}, points = {{0, 9.5}, {0, -9.5}}, color = {1, 37, 163}));
  connect(u_FractAdoptRate.y, adopting.u) annotation(Line(visible = true, origin = {-50, 1.319}, points = {{0, 61.319}, {0, -61.319}}, color = {1, 37, 163}));
  connect(adopting.portA, portA) annotation(Line(visible = true, origin = {-83.75, -35.596}, points = {{28.75, -34.404}, {-66.25, -34.404}, {-66.25, 35.596}, {-96.25, 35.596}}, color = {128, 0, 128}));
  connect(adopting.portB, portB) annotation(Line(visible = true, origin = {91.25, -35}, points = {{-126.25, -35}, {48.75, -35}, {48.75, 35}, {88.75, 35}}, color = {128, 0, 128}));
  connect(u_AdoptionFraction.y, conversionRate.u1) annotation(Line(visible = true, origin = {0, 32.5}, points = {{0, 29.5}, {0, -29.5}}, color = {1, 37, 163}));
  connect(parAdoptionFraction.y, conversionRate.u1) annotation(Line(visible = true, origin = {10, 48.131}, points = {{10, 20.869}, {10, 9.131}, {-10, 9.131}, {-10, -45.131}}, color = {1, 37, 163}));
  connect(conversionRate.y, converting.u) annotation(Line(visible = true, origin = {-5, -21.5}, points = {{0, 8.5}, {0, -8.5}}, color = {1, 37, 163}));
  connect(converting.y1, totalAdoptionRate.u1) annotation(Line(visible = true, origin = {22.125, -47.5}, points = {{-11.625, 2.5}, {-6.625, 2.5}, {-6.625, -2.5}, {24.875, -2.5}}, color = {1, 37, 163}));
  connect(u_otherAdopters.y, totalAdopters.u1) annotation(Line(visible = true, origin = {129.333, 54}, points = {{10.667, 8}, {10.667, -4}, {-21.333, -4}}, color = {1, 37, 163}));
  connect(parOtherAdopters.y, totalAdopters.u1) annotation(Line(visible = true, origin = {142.667, 58.333}, points = {{17.333, 16.667}, {17.333, -8.333}, {-34.667, -8.333}}, color = {1, 37, 163}));
  connect(totalAdopters.y, contactsAdopters.u2) annotation(Line(visible = true, origin = {75, 45}, points = {{17, 0}, {-17, 0}}, color = {1, 37, 163}));
  connect(potentialAdopters.stock, totalPotentialContacts.u2) annotation(Line(visible = true, origin = {-145.967, 23.667}, points = {{-3.984, -12.667}, {-3.984, 6.333}, {7.967, 6.333}}, color = {1, 37, 163}));
  connect(totalPotentialContacts.y, potAdoptConcentration.u2) annotation(Line(visible = true, origin = {-111.648, 37.5}, points = {{-10.352, -7.5}, {-3.352, -7.5}, {-3.352, 7.5}, {17.056, 7.5}}, color = {1, 37, 163}));
  connect(u_otherPopulation.y, totalPotentialContacts.u1) annotation(Line(visible = true, origin = {-152.667, 44}, points = {{-7.333, 18}, {-7.333, -9}, {14.667, -9}}, color = {1, 37, 163}));
  connect(parOtherPopulation.y, totalPotentialContacts.u1) annotation(Line(visible = true, origin = {-142.667, 45}, points = {{-2.333, 20}, {-2.333, -10}, {4.667, -10}}, color = {1, 37, 163}));
  connect(adjustedTotalAdopters.y, totalPotentialContacts.u3) annotation(Line(visible = true, origin = {-96.857, 20}, points = {{140.594, -5}, {-49.725, -5}, {-49.725, 5}, {-41.143, 5}}, color = {1, 37, 163}));
  connect(totalAdopters.y, adjustedTotalAdopters.u1) annotation(Line(visible = true, origin = {77.934, 32.5}, points = {{14.066, 12.5}, {2.066, 12.5}, {2.066, -12.5}, {-18.197, -12.5}}, color = {1, 37, 163}));
  connect(adopters.stock, adoptersNotInfluencing.u) annotation(Line(visible = true, origin = {150.024, 14.431}, points = {{-9.976, -3.431}, {-9.976, -0.931}, {9.976, -0.931}, {9.976, 5.292}}, color = {1, 37, 163}));
  connect(adopters.stock, adoptersInfluencing.u) annotation(Line(visible = true, origin = {140.024, 14.431}, points = {{0.024, -3.431}, {0.024, -0.931}, {-0.024, -0.931}, {-0.024, 5.292}}, color = {1, 37, 163}));
  connect(adoptersInfluencing.y, totalAdopters.u2) annotation(Line(visible = true, origin = {127.6, 39.689}, points = {{12.4, -3.966}, {12.4, 0.311}, {-19.6, 0.311}}, color = {1, 37, 163}));
  connect(adoptersNotInfluencing.y, totalAdopters.u2) annotation(Line(visible = true, origin = {143.933, 41.6}, points = {{16.067, -5.877}, {16.067, -1.6}, {-35.933, -1.6}}, color = {1, 37, 163}));
  connect(addAdoptersToPopulation.y, adjustedTotalAdopters.u2) annotation(Line(visible = true, origin = {84.184, 12.5}, points = {{12.816, 2.5}, {5.816, 2.5}, {5.816, -2.5}, {-24.447, -2.5}}, color = {1, 37, 163}));
  connect(addAdoptersToPopulation.u, adopters.stock) annotation(Line(visible = true, origin = {131.033, 13.667}, points = {{-18.033, 1.333}, {9.016, 1.333}, {9.016, -2.667}}, color = {1, 37, 163}));
  connect(doNotAddAdopters.y, adjustedTotalAdopters.u2) annotation(Line(visible = true, origin = {79.934, -5}, points = {{20.066, -15}, {0.066, -15}, {0.066, 15}, {-20.197, 15}}, color = {1, 37, 163}));
  connect(u_otherPopulation.u, dataIn.otherPopulation) annotation(Line(visible = true, origin = {-140, 92}, points = {{-20, -14}, {-20, -2}, {-35, -2}, {-35, -2}}, color = {1, 37, 163}));
  connect(dataIn.fractionalAdoptionRate, u_FractAdoptRate.u) annotation(Line(visible = true, origin = {-85, 92}, points = {{-90, -2}, {-90, -2}, {35, -2}, {35, -14}}, color = {0, 0, 128}));
  connect(dataIn.adoptionFraction, u_AdoptionFraction.u) annotation(Line(visible = true, origin = {-60, 92}, points = {{-115, -2}, {-115, -2}, {60, -2}, {60, -14}}, color = {0, 0, 128}));
  connect(dataIn.contactRate, u_ContactRate.u) annotation(Line(visible = true, origin = {-15, 92}, points = {{-160, -2}, {-160, -2}, {105, -2}, {105, -14}}, color = {0, 0, 128}));
  connect(dataIn.otherAdopters, u_otherAdopters.u) annotation(Line(visible = true, origin = {10, 92}, points = {{-185, -2}, {-185, -2}, {130, -2}, {130, -14}}, color = {0, 0, 128}));
  connect(adopting.y1, dataOut.adoptionRate) annotation(Line(visible = true, origin = {120.632, -57.901}, points = {{-155.132, -17.099}, {39.368, -17.099}, {39.368, 17.901}, {59.368, 17.901}}, color = {1, 37, 163}));
  connect(totalAdoptionRate.y, dataOut.totalAdoptionRate) annotation(Line(visible = true, origin = {140.594, -47.5}, points = {{-77.594, -7.5}, {19.406, -7.5}, {19.406, 7.5}, {39.406, 7.5}}, color = {1, 37, 163}));
  connect(converting.y1, dataOut.conversionRate) annotation(Line(visible = true, origin = {123.511, -42.5}, points = {{-113.011, -2.5}, {36.489, -2.5}, {36.489, 2.5}, {56.489, 2.5}}, color = {1, 37, 163}));
  connect(parFractAdoptRate.y, adopting.u) annotation(Line(visible = true, origin = {-40, 18.75}, points = {{10, 46.25}, {10, 16.25}, {-10, 16.25}, {-10, -78.75}}, color = {1, 37, 163}));
  connect(adopting.y1, totalAdoptionRate.u2) annotation(Line(visible = true, origin = {-6.875, -67.5}, points = {{-27.625, -7.5}, {-13.125, -7.5}, {-13.125, 7.5}, {53.875, 7.5}}, color = {1, 37, 163}));
  annotation(Diagram(coordinateSystem(extent = {{-180, -105}, {180, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})), Documentation(info = "<html>
<p class=\"aside\">This information is part of the Business Simulation&nbsp;Library (BSL). Please support this work and <a href=\"https://www.paypal.com/donate/?hosted_button_id=GXVZT8LD7CFXN\" style=\"font-weight:bold; color:orange; text-decoration:none;\">&#9658;&nbsp;donate</a>.</p>
<p>This is more or less the classical <em>Bass diffusion model</em>	 [<a href=\"modelica://BusinessSimulation.UsersGuide.References\">5</a>] that explains how new products get adopted in a population: &nbsp;Potential adopters turn into adopters being affected either by advertising or promotion (i.e., as <em>innovators</em>) or by social interaction (<em>\"word of mouth\"</em>) with adopters (i.e., as <em>imitators</em>).</p>
<p>The basic model for diffusion can also be used to model the spread of infectious diseases (→<a href=\"modelica://BusinessSimulation.Examples.SIR\">SIR</a>). Since the disease is ultimately spread by contact with an infected person, the <em>fractionalAdoptionRate</em> in this case should be zero.</p>
<p>While the structure in principle folllows Sterman's implementation [<a href=\"modelica://BusinessSimulation.UsersGuide.References\">3</a>, chapter 9], the component has been put in a more general form. We have to distinguish the following subgroups that make up the <strong>total population of potential contacts for social interaction</strong>:<p>
<ul>
<li><strong>Potential adopters</strong> (\"susceptible\")—the stock connected to <code>portA</code></li><br>
<li><strong>Adopters</strong> (\"infected\")—the stock connected to <code>portB</code></li><br>
<li><strong>Other population</strong> (\"immune\") the sub population that is neither adopter or potential adopter</li><br>
<li><strong>Other adopters</strong> (\"other infected\") the sub population that is also influencing potential adopters, but not the \"next stage\" (adopters/infected)</li>
</ul>
<p> Depending upon the structural parameter <code>nextStageIsInfluencing</code> we may choose to take the converted adopters out of the group of <em>influencers</em>, e.g., a freshly converted adopter may not yet be entusiastic enough, while more elaborate epidemic models like the SEIR model distinguish an <em>exposed</em> stage, that is not yet infectious.</p>
<h4>Implementation</h4>
<p>The behavior of the component is exactly specified by the following equations:</p>
<br>
<pre>totalPopulation = potentialAdopters + otherPopulation + adopters + otherAdopters<br>
adoptionRate = potentialAdopters &middot; fractionalAdoptionRate<br>
conversionRate = potentialAdopters&middot;(otherAdopters [+ adopters])&middot;adoptionFraction&middot;contactRate / totalPopulation<br>
totalAdoptionRate = adoptionRate + conversionRate
</pre><br>
<h4>Notes</h4>
<ul>
<li>All else being equal the process will produce S-shaped growth of adopters.</li><br>
<li>If advertising has no effect there needs to be a seed of initial adopters to set off the dynamics.</li><br>
<li>The classical Bass model only has two parameters. This can be obtained as a special case of the given structure by simply setting <em>contactRate</em> and&nbsp;<em>totalPopulation</em> to 1. The parameters <em>fractionalAdoptionRate&nbsp;</em>and <em>adoptionFraction&nbsp;</em>then correspond to the parameters used by Bass (note: the units for adoptionFraction are then different.</li>
</ul>
</html>", revisions = "<html>
<ul>
<li>Connectors <code>DataOutPort</code> and <code>DataInPort</code> changed to <code>encapsulated expandable connector</code> classes in v2.1.0.</li><br>
<li>Values for optional parameter inputs changed to <code>unspecified</code> in v2.1.0.</li><br>
</ul>
</html>"), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Line(visible = true, origin = {-86.207, 0}, points = {{0, 0}, {37.207, 0}}, color = {0, 128, 0}, thickness = 5, arrowSize = 10), Bitmap(visible = true, fileName = "", imageSource = "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
", extent = {{-50, -70}, {50, 70}}), Line(visible = true, origin = {50, 0}, points = {{0, 0}, {30, 0}}, color = {0, 128, 0}, thickness = 5, arrowSize = 10), Text(visible = true, origin = {0, 75}, textColor = {0, 128, 0}, extent = {{-100, -12}, {100, 12}}, textString = "Diffusion", fontName = "Lato", textStyle = {TextStyle.Bold}), Line(visible = true, origin = {0, 25.792}, points = {{-7.285, 0}, {7.285, 0}}, color = {128, 128, 128}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Polygon(visible = true, origin = {81, 0}, rotation = -90, lineColor = {0, 128, 0}, fillColor = {0, 128, 0}, fillPattern = FillPattern.Solid, points = {{0, 9}, {5, -5}, {-5, -5}}), Text(visible = true, origin = {-73.452, 37.479}, textColor = {76, 112, 136}, extent = {{-13.452, -20}, {13.452, 20}}, textString = "A"), Text(visible = true, origin = {73.452, -43.134}, textColor = {76, 112, 136}, extent = {{-13.452, -20}, {13.452, 20}}, textString = "B")}));
end Diffusion;
